package com.demo.java.concurrent.thread;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ThreadReplacePrintTest {
    public static void main(String[] args) {
        ThreadReplacePrintTest test = new ThreadReplacePrintTest();
//        test.synchronizedTest();
        test.volatileTest();
    }

    private int maxLoop = 100000;
    private int status = 0;
    private int i = 1;
    public void synchronizedTest() {
        new Thread(() -> {
            synchronized (this) {
                for (; i <= maxLoop; ) {
                    while (status != 0) {
                        try {
                            this.wait();
                        } catch (InterruptedException e) {
                        }
                    }
                    log.info("=== " + i++);
                    status = 1;
                    this.notifyAll();
                }
            }
        }, "t1").start();
        new Thread(() -> {

            synchronized (this) {
                for (; i <= maxLoop; ) {
                    while (status != 1) {
                        try {
                            this.wait();
                        } catch (InterruptedException e) {
                        }
                    }
                    log.info("=== " + i++);
                    status = 2;
                    this.notifyAll();
                }
            }
        }, "t2").start();
        new Thread(() -> {
            synchronized (this) {
                for (; i <= maxLoop; ) {
                    while (status != 2) {
                        try {
                            this.wait();
                        } catch (InterruptedException e) {
                        }
                    }
                    log.info("=== " + i++);
                    status = 0;
                    this.notifyAll();
                }
            }
        }, "t3").start();
    }

    private volatile int exchange = 0;
    private volatile int num = 1;

    public void volatileTest() {
        new Thread(() -> {
            for (; num <= maxLoop; ) {
                while (exchange != 0) {}
                log.info("===== " + num++);
                exchange = 1;
            }
        }, "t1").start();
        new Thread(() -> {
            for (; num <= maxLoop; ) {
                while (exchange != 1) {}
                log.info("===== " + num++);
                exchange = 2;
            }
        }, "t2").start();
        new Thread(() -> {
            for (; num <= maxLoop; ) {
                while (exchange != 2) {}
                log.info("===== " + num++);
                exchange = 0;
            }
        }, "t3").start();

    }
}
